using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Text;
using System.Threading;
using Ricciolo.PaperBoy.Feeds;
using System.Windows;
using System.Collections;
using System.Windows.Controls.Primitives;
using System.Windows.Controls;

namespace Ricciolo.PaperBoy.UI
{
    public class TreeListView : Ricciolo.Controls.TreeListView
    {

        public static DependencyProperty SelectedItemsProperty = DependencyProperty.Register("SelectedItems", typeof(IList), typeof(TreeListView), new FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault));

        private Thread refreshThread = null;

        public TreeListView()
        {
            this.Items.CurrentChanged += new EventHandler(Items_CurrentChanged);

            ScrollViewer.SetIsDeferredScrollingEnabled(this, true);
            VirtualizingStackPanel.SetVirtualizationMode(this, VirtualizationMode.Recycling);
            VirtualizingStackPanel.SetIsVirtualizing(this, true);
        }

        private void Items_CurrentChanged(object sender, EventArgs e)
        {
            // Auto select current item
            SetSelectedToCurrent();
        }

        protected override void OnItemsSourceChanged(IEnumerable oldValue, IEnumerable newValue)
        {
            base.OnItemsSourceChanged(oldValue, newValue);

            Thread oldThread = null;
            if (refreshThread != null && refreshThread.ThreadState == ThreadState.Running)
            {
                oldThread = refreshThread;
                refreshThread.Abort();
                refreshThread = null;
            }

            // Empy items for memory optimization
            IList itemsList = oldValue as IList;
            if (itemsList != null && (oldThread == null || oldThread.ThreadState != ThreadState.Aborted))
            {
                itemsList.Clear();
            }

            // Refresh items
            IRefresh refresh = newValue as IRefresh;
            if (refresh != null)
            {
                refreshThread = new Thread(OnRefresh);
                refreshThread.IsBackground = true;
                refreshThread.Start(new State(oldThread, refresh));
            }
        }

        #region State

        internal class State
        {
            public Thread OldThread;
            public IRefresh Refresh;

            public State(Thread oldThread, IRefresh refresh)
            {
                OldThread = oldThread;
                Refresh = refresh;
            }
        }

        #endregion

        private void OnRefresh(object obj)
        {
            State s = (State) obj;
            // Wait old thread
            if (s.OldThread != null)
                s.OldThread.Join(TimeSpan.FromSeconds(1));
            s.Refresh.Refresh();
        }

        private void SetSelectedToCurrent()
        {
            TreeListViewItem titem = this.ItemContainerGenerator.ContainerFromItem(this.Items.CurrentItem) as TreeListViewItem;
            if (titem != null && !titem.IsSelected)
            {
                titem.IsSelected = true;
            }
        }

        protected override void OnItemsChanged(System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
        {
            base.OnItemsChanged(e);

            if (e.Action == System.Collections.Specialized.NotifyCollectionChangedAction.Reset)
            {
                SetSelectedToCurrent();
            }
        }

        protected override System.Windows.DependencyObject GetContainerForItemOverride()
        {
            return new TreeListViewItem();
        }

        protected override void OnSelectedItemChanged(RoutedPropertyChangedEventArgs<object> e)
        {
            // Auto mark as read last item
            if (e.OldValue is FeedItem)
            {
                FeedItem fi = e.OldValue as FeedItem;
                if (fi != null)
                {
                    if (fi.SkipMarkAsRead)
                        fi.SkipMarkAsRead = false;
                    else
                        fi.IsRead = true;
                }
            }

            base.OnSelectedItemChanged(e);
        }

        public object SelectedItem
        {
            get { return base.SelectedItem; }
            set
            {
                TreeListViewItem item;
                // Deselect current items
                if (this.SelectedItem != null)
                {
                    item = this.ItemContainerGenerator.ContainerFromItem(this.SelectedItem) as TreeListViewItem;
                    if (item != null)
                        item.IsSelected = false;
                }

                item = this.ItemContainerGenerator.ContainerFromItem(value) as TreeListViewItem;
                if (item != null)
                {
                    item.IsSelected = true;
                }
            }
        }

    }

    public class TreeListViewItem : Ricciolo.Controls.TreeListViewItem
    {

        protected override void OnMouseRightButtonDown(System.Windows.Input.MouseButtonEventArgs e)
        {
            if (!e.Handled)
            {
                // If already selected not deselect all
                if (!this.IsSelected)
                    this.IsSelected = true;
            }
        }

        protected override void OnExpanded(RoutedEventArgs e)
        {
            base.OnExpanded(e);

            if (this.ItemsSource is ICollectionView)
                ((ICollectionView)this.ItemsSource).Refresh();
        }

    }
}
